package com.beiding.codecreater.core.render;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

class URepeatBlock {

    //将内部所有节点处理成树
    void pairToTree(List<Pair> pairs) {

        //同级节点过

        for (Pair pair : pairs) {
            pairToTree(pair, pairs);
            if (pair.toRootInners.size() > 0) {

                //递归处理
                pairToTree(pair.toRootInners);
            }
        }

    }

    private Pair cloneRefPair(Pair p, Pair reference) {

        int s = reference.blockStart.endIndex;
        Pair c = new Pair();
        BlockStart blockStart = new BlockStart();
        BlockEnd blockEnd = new BlockEnd();

        blockStart.startIndex = p.blockStart.startIndex - s;
        blockStart.endIndex = p.blockStart.endIndex - s;
        blockStart.text = p.blockStart.text;
        blockStart.repeat = p.blockStart.repeat;
        blockStart.condition = p.blockStart.condition;

        blockEnd.startIndex = p.blockEnd.startIndex - s;
        blockEnd.endIndex = p.blockEnd.endIndex - s;
        blockEnd.text = p.blockEnd.text;

        c.blockEnd = blockEnd;
        c.blockStart = blockStart;

        c.body = p.body;

        //减去根节点的层级接口
        c.hierarchy = p.hierarchy - reference.hierarchy - 1;

        return c;
    }

    private void pairToTree(Pair pair, List<Pair> pairs) {

        int s = pair.blockStart.startIndex;

        int e = pair.blockEnd.endIndex;

        List<Pair> inner = new ArrayList<>();
        for (Pair p : pairs) {

            //内部节点包含所有元素
            if (p.hierarchy > pair.hierarchy && s < p.blockStart.startIndex && p.blockEnd.endIndex < e) {
                Pair clonePair = cloneRefPair(p, pair);
                inner.add(clonePair);
            }
        }

        pair.toRootInners = inner;

    }

    //从模块中解析出所有成对存在的节点
    List<Pair> parsePairs(String s) {

        //String s = FileUtils.readClassPathResourceAsString("template/Template.java");

        //开始从头进行解析
        Pattern blockStartPattern = Pattern.compile("<[ \n\t]*" + startTagName + "([ \n\t]+v-repeat=\"([a-zA-Z0-9 _.\\[\\]]+)\")?([ \n\t]+v-if=\"([a-zA-Z0-9 _.\\[\\]]+)\")?[ \n\t]*>");

        Matcher matcher = blockStartPattern.matcher(s);

        List<BlockStart> starts = new LinkedList<>();

        while (matcher.find()) {
            BlockStart blockStart = new BlockStart();
            blockStart.startIndex = matcher.start();
            blockStart.endIndex = matcher.end();
            String rt = matcher.group(2);
            if (rt != null) {
                blockStart.repeat = rt.trim();
            }
            String cd = matcher.group(4);
            if (cd != null) {
                blockStart.condition = cd.trim();
            }
            blockStart.text = matcher.group();
            starts.add(blockStart);
        }

        Pattern blockEndPattern = Pattern.compile("</[ \n\t]*" + endTagName + "[ \n\t]*>");

        List<BlockEnd> ends = new LinkedList<>();

        matcher = blockEndPattern.matcher(s);

        while (matcher.find()) {
            BlockEnd end = new BlockEnd();
            end.startIndex = matcher.start();
            end.endIndex = matcher.end();

            //整个标签体中的文本
            end.text = matcher.group();
            ends.add(end);
        }


        //将开始节点和结束节点进行配对操作


        List<BlockTag> tags = new ArrayList<>();

        tags.addAll(starts);
        tags.addAll(ends);

        List<Pair> pairList = new ArrayList<>();

        if (tags.size() > 0) {

            BlockTag blockTag = tags.get(0);
            if (!(blockTag instanceof BlockStart)) {
                throw new RuntimeException("块节点中开始结束标签不匹配");
            }
            tags.sort((a, b) -> a.startIndex - b.endIndex);
            Stack<Pair> pairs = new Stack<>();

            for (BlockTag tag : tags) {
                if (tag instanceof BlockStart) {
                    Pair pair = new Pair();
                    pair.blockStart = (BlockStart) tag;
                    pair.hierarchy = pairs.size();
                    pairs.push(pair);
                } else {
                    Pair pop = pairs.pop();
                    if (pop == null) {
                        throw new RuntimeException("块节点中开始结束标签不匹配");
                    }
                    pop.blockEnd = (BlockEnd) tag;
                    //体
                    pop.body = s.substring(pop.blockStart.endIndex, pop.blockEnd.startIndex);
                    pairList.add(pop);
                }
            }

            if (pairs.size() != 0) {
                throw new RuntimeException("块节点中开始结束标签不匹配");
            }

/*
            for (Pair pair : pairList) {
                System.out.println(pair.blockStart.startIndex + "->" + pair.blockEnd.endIndex);
            }*/

        }

        return pairList;

    }

    private int id = 1;


    private String startTagName;
    private String endTagName;


    URepeatBlock(String startTagName, String endTagName) {
        this.startTagName = startTagName;
        this.endTagName = endTagName;
    }

    private String createHolder() {
        return "<$$ blockHolder_" + (id++) + " $$>";
    }


    //进行区块替换,只替换最外层节点
    String replaceBlock(String s, List<Pair> pairs) {

        StringBuilder builder = new StringBuilder();

        int end = 0;

        //开始
        for (Pair pair : pairs) {
            if (pair.hierarchy == 0) {
                builder.append(s, end, pair.blockStart.startIndex);
                String id = createHolder();
                builder.append(id);
                end = pair.blockEnd.endIndex;

                pair.holder = id;

            }
        }

        if (end <= s.length() - 1) {
            builder.append(s.substring(end));
        }

        return builder.toString();

    }


    static class Pair implements Cloneable {

        private String holder;

        private List<Pair> toRootInners;

        private BlockStart blockStart;
        private BlockEnd blockEnd;

        private String body;

        String getHolder() {
            return holder;
        }

        List<Pair> getToRootInners() {
            return toRootInners;
        }


        String getBody() {
            return body;
        }

        private int hierarchy;

        int getHierarchy() {
            return hierarchy;
        }

        BlockStart getBlockStart() {
            return blockStart;
        }

        BlockEnd getBlockEnd() {
            return blockEnd;
        }

        @Override
        public String toString() {
            return blockStart.startIndex + "->" + blockEnd.endIndex;
        }

    }

    static class BlockStart extends BlockTag {
        //重复表达式
        String repeat;
        String condition;

        public String getCondition() {
            return condition;
        }

        String getRepeat() {
            return repeat;
        }
    }


    static class BlockEnd extends BlockTag {
    }


    static class BlockTag {

        //内含文本
        String text;
        //开始坐标
        int startIndex;
        //结束坐标
        int endIndex;

        String getText() {
            return text;
        }

        int getStartIndex() {
            return startIndex;
        }

        int getEndIndex() {
            return endIndex;
        }

    }


}
